<?php
/**
 * Định dạng biểu mẫu cấu hình tabbed block
 *
 */
function theme_tabbed_block_form ($form) {
  menu_set_active_item('admin/build/block/tabbed-block');
  
  if (($selected_tabs = element_children($form['selected_tabs']))) {
  	$blocks = tabbed_block_get_blocks();
  	
  	$tabs = array ();
  	
    for ($i = 0, $number = count ($selected_tabs); $i < $number; ++$i) {
      list ($module, $delta) = explode (':', $selected_tabs[$i]);
      
      $form['selected_tabs'][$selected_tabs[$i]]['weight']['#attributes']['class'] = 'tabbed-block-weight';
      
      // nếu block tương ứng có field argument
      if ($form['selected_tabs'][$selected_tabs[$i]]['argument']) {
        $tabs[] = array (
          'data' => array (
            $blocks[$module][$selected_tabs[$i]],
            drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['title']) . theme ('fieldset', array (
              '#title' => t('Arguments'),
              '#collapsible' => true,
              '#collapsed' => true,
              '#value' => drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['argument'])
            )),
            drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['weight']),
            drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['user-trash'])
          ),
          'class' => 'draggable'
        );
      }
      else {
        $tabs[] = array (
          'data' => array (
            $blocks[$module][$selected_tabs[$i]],
            drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['title']),
            drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['weight']),
            drupal_render ($form['selected_tabs'][$selected_tabs[$i]]['user-trash'])
          ),
          'class' => 'draggable'
        );
      }
    }
    
    $output .= theme (
      'table', 
      array (t('Block'), t('Override title'), t('Weight'), t('Ops')),
      $tabs,
      array('id' => 'tabbed-block-tabs')
    );
  }
  
  // Tell Drupal to add the tabledrag.js library
  drupal_add_tabledrag (
    'tabbed-block-tabs', 
    'order', 
    'self', 
    'tabbed-block-weight'
  );
  
  return drupal_render ($form['title']) . $output . drupal_render ($form);
}

/**
 * Tabbed block adding form
 *
 */
function tabbed_block_form ($form_state, $config = array ()) {
  if (!empty ($config['delta']) && !$form_state['storage']['tabs']) {
    if (!$form_state['values']['title']) {
      $form_state['values']['title'] = $config['title'];
    }
    
    foreach ($config['data'] as $key => $val) {
      $form_state['storage']['tabs'][$key] = $val;
    }
  }
  
  if (is_numeric ($config['delta'])) {
    $form['delta'] = array (
      '#type' => 'value',
      '#value' => $config['delta']
    );
  }
  
	drupal_set_title (t('Add new tabbed block'));
	
	// Tiêu đề của tabbed-block này
	$form['title'] = array (
    '#type' => 'textfield',
    '#required' => true,
    '#title' => t('Block title'),
    '#default_value' => $form_state['values']['title'],
	  '#description' => t('Every tabbed block should have a unique name for easier to manage.') 
	);
	
  $tabbed_block_path = drupal_get_path ('module', 'tabbed_block');
  
  $tabs[''] = t('Select one');
  
  // Lấy các block của hệ thống
  $tabs = array_merge($tabs, tabbed_block_get_blocks());
  
  // Form hiện tại có các tab
  if (is_array ($form_state['storage']['tabs']) && count ($form_state['storage']['tabs']) > 0) {
    // sắp xếp lại thứ tự trình bày
    uasort ($form_state['storage']['tabs'], "_tabbed_block_compare");
    
    foreach ($form_state['storage']['tabs'] as $tab => $val) {
      list ($module, $delta) = explode (':', $tab);
      $selected_tabs["$module:$delta"] = "<i>($module)</i> " . $tabs[$module]["$module:$delta"];
      
      $form['selected_tabs']["$module:$delta"] = array (
        '#tree' => true,
        'module' => array (
          '#type' => 'value',
          '#value' => $module
        ),
        'title' => array (
          '#type' => 'textfield',
          '#default_value' => $val['title']
        ),
        'weight' => array (
          '#type' => 'weight',
          '#delta' => 10,
          '#default_value' => $val['weight']
        ),
        'user-trash' => array (
          '#type' => 'image_button',
          '#src' => drupal_get_path ('module', 'tabbed_block') . '/images/user-trash.png'
        )
      );
      
      // nếu block được cung cấp bởi views
      if ($module == 'views') {
        $form['selected_tabs']["$module:$delta"]['argument'] = array (
          '#type' => 'textfield',
          '#title' => t('Argument'),
          '#default_value' => $val['argument']
        );
      }
      
      // Không hiển thị các block đã được chọn vào lại hộp chọn
      unset ($tabs[$module]["$module:$delta"]);
    }
    
    // Ẩn đi các module không có cung cấp block nào
    foreach ($tabs as $module => $val) {
      if (is_array ($tabs[$module]) && !count($tabs[$module])) {
        unset ($tabs[$module]);
      }
    }
  }
  
  // Tab selection box
  $form['tab'] = array (
    '#type' => 'select',
    '#title' => t('Add new tab'),
    '#options' => $tabs,
    '#description' => t('Note: When the tabbed block is displayed, it will break the access rule of its tabs (known as a Drupal block).')
  );
  
  // Button controls
  $form['buttons'] = array (
    'add_tab' => array (
      '#type' => 'submit',
      '#value' => t('Add tab')
    ),
    'submit' => array (
      '#type' => 'submit',
      '#value' => t('Save')
    )
  );
  
  if (!empty($config['delta'])) {
    $form['buttons']['delete'] = array (
      '#type' => 'submit',
      '#value' => t('Delete')
    );
  }
  
  return $form;
}

/**
 * Validator for tabbed block adding form
 */
function tabbed_block_form_validate ($form, &$form_state) {
  // Người dùng nhấp nút thêm tab
  if ($form_state['values']['op'] == t('Add tab')) {
    // hộp chọn tab có giá trị rỗng
    if (empty ($form_state['values']['tab'])) {
      form_set_error ('tab', t('You should submit a valid block to add to this one as a tab.'));
    }
    else {
      $block_list = tabbed_block_get_blocks();
      
      // tab được thêm vào không phải là một block trong hệ thống 
      if (!tabbed_block_is_valid_block ($form_state['values']['tab'])) {
        form_set_error ('tab', t('Invalid block.'));
      }
    }
  }
  
  if ($form_state['values']['op'] == t('Save')) {
    // Không thể thực hiện kịch bản lưu, nếu như người dùng chưa chọn tab nào
    if (count ($form_state['storage']['tabs']) < 2) {
      form_set_error ('tab', t('You have to select at least 2 tabs.'));
    }
    // Không cho block title trùng
    else {
      if (is_numeric ($form_state['values']['delta'])) {
        $number = db_result (db_query (
          "SELECT COUNT(*) FROM {tabbed_block} WHERE title = '%s' AND delta != %d",
          $form_state['values']['title'], $form_state['values']['delta']
        ));
      }
      else {
        $number = db_result (db_query (
          "SELECT COUNT(*) FROM {tabbed_block} WHERE title = '%s'",
          $form_state['values']['title']
        ));
      }
      
      if ($number > 0) {
        form_set_error ('title', t('Block title is already existed. Please choose another one.'));
      }
    }
  }
}

/**
 * Submit handler for tabbed block adding form
 */
function tabbed_block_form_submit ($form, &$form_state) {
  // Lưu các thiết lập vào storage
  foreach ($form_state['values'] as $key => $val) {
    if (preg_match ('|^.+:[a-z0-9_-]+$|i', $key)) {
      list ($module, $delta) = explode (':', $key);
      $form_state['storage']['tabs']["$module:$delta"]['title'] = $val['title'];
      $form_state['storage']['tabs']["$module:$delta"]['weight'] = $val['weight'];
    }
    
    // Xoá tab
    if ($val['user-trash'] == 1) {
      unset ($form_state['storage']['tabs']["$module:$delta"]);
    }
  }
  
  switch ($form_state['values']['op']) {
    case t('Add tab'):
      $tab = $form_state['values']['tab'];
      
      // Save selected tab to form's cache
      $form_state['storage']['tabs'][$tab] = array (
        'title' => '',
        'weight' => 0
      );
      break;
    case t('Save'):
      tabbed_block_tabs_save ($form_state['values']);
      
      // Redirect usre to block listing page 
      $form_state['redirect'] = 'admin/build/block';
      
      drupal_set_message (t(
        'Saved tabbed block <strong>!title</strong>',
        array ('!title' => check_plain ($form_values['values']['title']))
      ));
      
      drupal_goto ('admin/build/block');
      break;
    case t('Delete'):
      tabbed_block_delete ($form_state['values']['delta']);
      
      // Redirect usre to block listing page 
      $form_state['redirect'] = 'admin/build/block';
      
      drupal_set_message (t(
        'Deleted tabbed block <strong>!title</strong>',
        array ('!title' => check_plain ($form_values['values']['title']))
      ));
      
      drupal_goto ('admin/build/block');
      break;
  }
}

/**
 * Helper function for block's tabs saving
 */
function tabbed_block_tabs_save (&$edit) {
  $config = array ();
  if (is_numeric ($edit['delta'])) {
    $config['delta'] = $edit['delta'];
  }
  $config['title'] = $edit['title'];
  $config['data'] = array ();
  
  foreach ($edit as $key => $val) {
    if (preg_match ('|^.+:[a-z0-9_-]+$|i', $key)) {
      $row = array ();
      
      if (!empty ($val['title'])) {
        $row['title'] = check_plain (trim ($val['title']));
      }
      
      if (!empty ($val['weight'])) {
        $row['weight'] = check_plain (trim ($val['weight']));
      }
      
      if (!empty ($val['argument'])) {
        $row['argument'] = check_plain (trim ($val['argument']));
      }
      
      $config['data'][$key] = $row;
    }
  }
  
  $config['data'] = serialize ($config['data']);
  
  tabbed_block_save ($config);
}

/**
 * Lấy tất cả các block của hệ thống, không được sinh ra bởi module tabbed-block
 */
function tabbed_block_get_blocks () {
  static $block_list = array ();

  if (!$block_list) {
    foreach (module_implements ('block') as $module) {
      if (is_array ($module_blocks = module_invoke ($module, 'block', 'list'))) {
        foreach ($module_blocks as $number => $block) {
          if ($module != 'tabbed_block') {
            $block_list[$module][$module.':'.$number] = $block['info'];
          }
        };
      }
    }
  }
  
  return $block_list;
}

/**
 * Check a block is an existing block
 */
function tabbed_block_is_valid_block ($tab) {
  $block_list = tabbed_block_get_blocks();
  
  list ($module, $delta) = explode (':', $tab);
  
  return isset ($block_list[$module]["$module:$delta"]);
}
